package com.family.gmall.order.controller;

import com.family.gmall.cart.client.CartFeignClient;
import com.family.gmall.common.result.Result;
import com.family.gmall.common.util.AuthContextHolder;
import com.family.gmall.model.order.CartInfo;
import com.family.gmall.model.order.OrderDetail;
import com.family.gmall.model.order.OrderInfo;
import com.family.gmall.model.user.UserAddress;
import com.family.gmall.order.service.OrderInfoService;
import com.family.gmall.product.client.ProductFeignClient;
import com.family.gmall.user.client.UserFeignClient;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import jodd.util.StringUtil;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @Auther: family
 * @Date: 2023/8/5 19:05
 * @Description:
 */
@RestController
@RequestMapping("/api/order")
public class OrderApiController {

    @Resource
    private UserFeignClient userFeignClient;

    @Resource
    private CartFeignClient cartFeignClient;

    @Resource
    private ProductFeignClient productFeignClient;

    @Resource
    private OrderInfoService orderInfoService;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @ApiOperation("提交订单")
    @ApiImplicitParam(name = "orderInfo", value = "orderInfo", required = true)
    @PostMapping("auth/submitOrder")
    public Result submitOrder(@RequestBody OrderInfo orderInfo, HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        orderInfo.setUserId(Long.parseLong(userId));
        // 获取前台页面的流水号
        String tradeNo = request.getParameter("tradeNo");
        if (!orderInfoService.checkTradeCode(userId, tradeNo)) {
            // 比较失败！
            return Result.fail().message("不能重复提交订单！");
        }
        //  删除流水号
        orderInfoService.deleteTradeNo(userId);

        List<String> errorList = new ArrayList<>();
        List<CompletableFuture> futureList = new ArrayList<>();
        //验证库存
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {

            CompletableFuture<Void> checkStockFuture = CompletableFuture.runAsync(() -> {
                //验证库存
                boolean result = orderInfoService.checkStock(
                        orderDetail.getSkuId(),
                        Integer.parseInt(orderDetail.getSkuNum()));
                if (!result) {
                    errorList.add(orderDetail.getSkuName() + "库存不足！");
                }
            }, threadPoolExecutor);
            futureList.add(checkStockFuture);

            CompletableFuture<Void> checkPriceFuture = CompletableFuture.runAsync(() -> {
                //验证价格
                BigDecimal skuPrice = productFeignClient.getSkuPrice(orderDetail.getSkuId());
                if (orderDetail.getOrderPrice().compareTo(skuPrice) != 0) {
                    //重新查询价格
                    cartFeignClient.loadCartCache(userId);
                    errorList.add(orderDetail.getSkuName() + "价格有变动！");
                }
            }, threadPoolExecutor);
            futureList.add(checkPriceFuture);
        }
        //合并线程
        CompletableFuture.allOf(futureList.toArray(new CompletableFuture[futureList.size()])).join();
        if (errorList.size() > 0) {
            return Result.fail().message(StringUtil.join(errorList, ","));
        }
        //验证通过，保存订单！
        Long orderId = orderInfoService.saveOrderInfo(orderInfo);
        return Result.ok(orderId);
    }


    @ApiOperation("确认订单")
    @ApiImplicitParam(name = "request", value = "request", required = true)
    @GetMapping("auth/trade")
    public Result<Map<String, Object>> trade(HttpServletRequest request) {
        String userId = AuthContextHolder.getUserId(request);
        List<UserAddress> userAddressList = userFeignClient.findUserAddressListByUserId(userId);
        List<CartInfo> cartCheckedList = cartFeignClient.getCartCheckedList(userId);

        ArrayList<OrderDetail> detailArrayList = new ArrayList<>();
        cartCheckedList.forEach(item -> {
            OrderDetail orderDetail = new OrderDetail();
            orderDetail.setSkuId(item.getSkuId());
            orderDetail.setSkuName(item.getSkuName());
            orderDetail.setImgUrl(item.getImgUrl());
            orderDetail.setSkuNum(item.getSkuNum().toString());
            orderDetail.setOrderPrice(item.getSkuPrice());
            detailArrayList.add(orderDetail);
        });
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setOrderDetailList(detailArrayList);
        orderInfo.sumTotalAmount();
        Map<String, Object> result = new HashMap<>();
        result.put("userAddressList", userAddressList);
        result.put("detailArrayList", detailArrayList);
        result.put("totalNum", detailArrayList.size());
        result.put("totalAmount", orderInfo.getTotalAmount());
        // 获取流水号
        String tradeNo = orderInfoService.getTradeNo(userId);
        result.put("tradeNo", tradeNo);

        return Result.ok(result);
    }

    @ApiOperation("内部调用获取订单")
    @ApiImplicitParam(name = "orderId", value = "orderId", required = true)
    @GetMapping("inner/getOrderInfo/{orderId}")
    public OrderInfo getOrderInfo(@PathVariable(value = "orderId") Long orderId) {
        return orderInfoService.getOrderInfo(orderId);
    }
}
